package com.ideaaedi.commonspring.lite.register;

import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.Ordered;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.lang.NonNull;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.ServiceLoader;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 功能注册器
 *
 * @author <font size = "20" color = "#3CAA3C"><a href="https://gitee.com/JustryDeng">JustryDeng</a></font> <img
 * src="https://gitee.com/JustryDeng/shared-files/raw/master/JustryDeng/avatar.jpg" />
 * @since 2021.0.5.A
 */
public class FeatureRegistrarFace implements ImportBeanDefinitionRegistrar {
    
    /**
     * 指定要排除的类. 全类名，多个使用逗号分隔
     */
    public static final String EXCLUDES_FEATURE_REGISTRAR = FeatureRegistrarFace.class.getName() + ".excludes";
    
    protected FeatureRegistrarProxy featureRegistrarProxy;
    
    public FeatureRegistrarFace() {
        init();
    }
    
    protected void init() {
        Set<String> excludeSet = new HashSet<>();
        String excludes = System.getProperty(EXCLUDES_FEATURE_REGISTRAR);
        if (excludes != null) {
            excludeSet.addAll(
            Arrays.stream(excludes.split(","))
                    .map(String::trim)
                    .filter(s -> !s.isEmpty())
                    .collect(Collectors.toSet())
            );
        }
        
        ServiceLoader<FeatureRegistrarProxy> serviceLoader = ServiceLoader.load(FeatureRegistrarProxy.class);
        Iterator<FeatureRegistrarProxy> iterator = serviceLoader.iterator();
        List<FeatureRegistrarProxy> list = new ArrayList<>(8);
        while (iterator.hasNext()) {
            FeatureRegistrarProxy next = iterator.next();
            if (excludeSet.contains(next.getClass().getCanonicalName())) {
                continue;
            }
            list.add(next);
        }
        list.sort(Comparator.comparing(Ordered::getOrder));
        if (list.size() > 0) {
            this.featureRegistrarProxy = list.get(0);
        }
    }
    
    /**
     * 注册bean
     */
    @Override
    public void registerBeanDefinitions(@NonNull AnnotationMetadata annotationMetadata, @NonNull BeanDefinitionRegistry registry) {
        if (featureRegistrarProxy == null) {
            throw new IllegalStateException("There is no corresponding feature registrar, please introduce the relevant implementation.");
        }
        featureRegistrarProxy.registerBeanDefinitions(annotationMetadata, registry);
    }
}
